package com.geekstudy.week4;


import com.geekstudy.week4.api.MessageApi;
import com.geekstudy.week4.api.service.MessageService;
import com.geekstudy.week4.proxy.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;

/**
 * https://gitee.com/geektime-geekbang/mercyblitz-projects/tree/master/projects/stage-1/middleware-frameworks/my-interceptor
 * my-interceptor/src/main/java/org/geektimes/interceptor/cglib/InterceptorEnhancer.java
 *
 *
 * 将 my-interceptor 工程代码增加 JDK 动态代理, 将 @BulkHead 等注解标注在接口上, 实现方法拦截
 * 1. 通过 JDK 动态代理实现类似 InterceptorEnhancer 的代码
 * 2. 实现 JDK 动态代理方法的 InvocationContext
 *
 */
// @SpringBootApplication
public class Week4SpringBootMain {

    static final Logger logger = LoggerFactory.getLogger(Week4SpringBootMain.class);

    public static void main(String[] args) {
        // ConfigurableApplicationContext configurableApplicationContext = SpringApplication.run(Week4SpringBootMain.class, args);
        // logger.info("beanCount:{} ", configurableApplicationContext.getBeanDefinitionCount());

        // 使用简单的 JDK 动态代理
        MessageApi messageApi = new MessageService();
        InvocationHandler invocationHandler = new DemoDynamicProxy(messageApi);
        Object proxyObject = Proxy.newProxyInstance(MessageApi.class.getClassLoader(), new Class<?>[]{MessageApi.class}, invocationHandler);
        if(proxyObject instanceof MessageApi) {
            MessageApi api = (MessageApi)proxyObject;
            String result = api.sayMessage("Demo 2021!");
            logger.info("result:{} ", result);
        }


        // Exception in thread "main" java.lang.IllegalArgumentException: com.geekstudy.week4.api.service.MessageService is not an interface
        // 实现 JDK 动态代理方法的 InvocationContext
        MessageApi apiDemo = new MessageService();
        DynamicProxyInvocationContext dynamicProxyInvocationContext = new DynamicProxyInvocationContext();
        MessageApi messageApiDemo = dynamicProxyInvocationContext.addTarget(apiDemo, MessageApi.class);
        String demoContext = messageApiDemo.sayMessage("Use Context Test");
        logger.info("demoContext:{}", demoContext);

        //DynamicProxyAdapter dynamicProxyAdapter = new DynamicProxyAdapter(dynamicProxyInvocationContext);
        //dynamicProxyAdapter.invoke(MessageApi.class, )

        // 通过 JDK 动态代理实现类似 InterceptorEnhancer 的代码
        DynamicProxyInterceptorEnhancer dynamicProxyInterceptorEnhancer = new DynamicProxyInterceptorEnhancer();
        DynamicEnhancer dynamicEnhancer = dynamicProxyInterceptorEnhancer.enhance(new MessageService(), MessageApi.class);
        Object enhancerProxy = dynamicEnhancer.getProxy();
        if(enhancerProxy instanceof MessageApi) {
            MessageApi enhancerApi = (MessageApi)enhancerProxy;
            logger.info("enhance Messgae:{} ", enhancerApi.sayMessage("Enhance Message!!!"));
        }
        logger.info("enhance read Annotation useDemoBulkHead:{} executeTimes:{} ", dynamicEnhancer.getDemoBulkHead(), dynamicEnhancer.getDemoBulkHeadExecuteTimes());

    }
}
